<template>
  <div class="file-upload-container">
    <!-- 文件上传区域 -->
    <el-upload
      ref="uploadRef"
      :auto-upload="false"
      :multiple="multiple"
      :accept="accept"
      :before-upload="beforeUpload"
      :on-change="handleFileChange"
      :file-list="fileList"
      :list-type="listType"
      :limit="limit"
      :on-exceed="handleExceed"
    >
      <template #trigger>
        <el-button type="primary" :icon="Upload">
          {{ uploadText }}
        </el-button>
      </template>
      
      <template #tip v-if="showTip">
        <div class="el-upload__tip">{{ tipText }}</div>
      </template>
    </el-upload>

    <!-- 操作按钮 -->
    <div class="upload-actions" style="margin-top: 10px;">
      <el-button 
        type="success" 
        @click="submitUpload"
        :disabled="!hasFiles || uploading"
        :loading="uploading"
      >
        {{ uploading ? '上传中...' : '确认上传' }}
      </el-button>
      
      <el-button @click="clearFiles" :disabled="!hasFiles">
        清空文件
      </el-button>
    </div>

    <!-- 当前关联的文件显示 -->
    <div class="current-file" v-if="currentFile">
      <el-divider content-position="left">当前文件</el-divider>
      <div class="file-item">
        <el-image 
          v-if="isImage(currentFile.fileType)"
          :src="currentFile.accessUrl" 
          style="width: 100px; height: 100px; margin-right: 10px;"
          fit="cover"
          :preview-src-list="[currentFile.accessUrl]"
        />
        <div class="file-info">
          <p><strong>文件名：</strong>{{ currentFile.fileName }}</p>
          <p><strong>文件大小：</strong>{{ formatFileSize(currentFile.fileSize) }}</p>
          <p><strong>文件类型：</strong>{{ currentFile.fileType }}</p>
          <div class="file-actions">
            <el-button 
              size="small" 
              type="primary" 
              @click="previewFile"
              v-if="canPreview(currentFile.fileType)"
            >
              预览
            </el-button>
            <el-button 
              size="small" 
              @click="downloadFile"
            >
              下载
            </el-button>
            <el-button 
              size="small" 
              type="danger" 
              @click="removeCurrentFile"
            >
              删除
            </el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {computed, ref} from 'vue'
import {Upload} from '@element-plus/icons-vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import {fileApi} from '@/api/file'

const props = defineProps({
  // 是否支持多文件
  multiple: {
    type: Boolean,
    default: false
  },
  // 接受的文件类型
  accept: {
    type: String,
    default: '.jpg,.jpeg,.png,.gif,.pdf,.doc,.docx'
  },
  // 文件大小限制（MB）
  maxSize: {
    type: Number,
    default: 10
  },
  // 文件列表显示类型
  listType: {
    type: String,
    default: 'text' // text, picture, picture-card
  },
  // 最大文件数量
  limit: {
    type: Number,
    default: 1
  },
  // 上传按钮文字
  uploadText: {
    type: String,
    default: '选择文件'
  },
  // 是否显示提示
  showTip: {
    type: Boolean,
    default: true
  },
  // 提示文字
  tipText: {
    type: String,
    default: '支持jpg、png、pdf等格式，文件大小不超过10MB'
  },
  // 当前关联的文件信息
  currentFile: {
    type: Object,
    default: null
  }
})

const emit = defineEmits(['upload-success', 'upload-error', 'file-removed'])

const uploadRef = ref()
const fileList = ref([])
const uploading = ref(false)

// 计算属性
const hasFiles = computed(() => fileList.value.length > 0)

// 文件校验
const beforeUpload = (file) => {
  // 检查文件大小
  const isValidSize = file.size / 1024 / 1024 < props.maxSize
  if (!isValidSize) {
    ElMessage.error(`文件大小不能超过${props.maxSize}MB`)
    return false
  }

  // 检查文件类型
  const fileExtension = getFileExtension(file.name)
  const allowedTypes = props.accept.split(',').map(type => type.trim().replace('.', ''))
  if (!allowedTypes.includes(fileExtension.toLowerCase())) {
    ElMessage.error(`不支持的文件类型：${fileExtension}`)
    return false
  }

  return true
}

// 文件选择变化
const handleFileChange = (file, files) => {
  fileList.value = files
}

// 文件数量超限
const handleExceed = (files, uploadFiles) => {
  ElMessage.warning(`最多只能上传${props.limit}个文件`)
}

// 提交上传
const submitUpload = async () => {
  if (!hasFiles.value) return

  uploading.value = true
  try {
    const files = fileList.value.map(item => item.raw)
    let result

    if (props.multiple) {
      result = await fileApi.uploadFiles(files)
    } else {
      result = await fileApi.uploadFile(files[0])
    }

    // 统一向父组件传递响应数据本身（已由请求拦截器解包为 data）
    emit('upload-success', result)
    ElMessage.success('文件上传成功')
    clearFiles()
  } catch (error) {
    emit('upload-error', error)
    ElMessage.error('文件上传失败：' + (error.message || '未知错误'))
  } finally {
    uploading.value = false
  }
}

// 清空文件
const clearFiles = () => {
  fileList.value = []
  uploadRef.value?.clearFiles()
}

// 预览文件
const previewFile = () => {
  if (props.currentFile?.accessUrl) {
    window.open(props.currentFile.accessUrl, '_blank')
  }
}

// 下载文件
const downloadFile = () => {
  if (props.currentFile?.accessUrl) {
    const link = document.createElement('a')
    link.href = props.currentFile.accessUrl
    link.download = props.currentFile.fileName
    link.click()
  }
}

// 删除当前文件
const removeCurrentFile = async () => {
  try {
    await ElMessageBox.confirm('确定要删除该文件吗？', '提示', {
      type: 'warning'
    })
    
    emit('file-removed')
    ElMessage.success('文件删除成功')
  } catch (error) {
    // 用户取消
  }
}

// 工具函数
const getFileExtension = (filename) => {
  return filename.split('.').pop() || ''
}

const isImage = (fileType) => {
  const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
  return imageTypes.includes(fileType?.toLowerCase())
}

const canPreview = (fileType) => {
  const previewTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'pdf']
  return previewTypes.includes(fileType?.toLowerCase())
}

const formatFileSize = (bytes) => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
</script>

<style scoped>
.file-upload-container {
  padding: 20px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #fff;
}

.upload-actions {
  display: flex;
  gap: 10px;
}

.current-file {
  margin-top: 20px;
}

.file-item {
  display: flex;
  align-items: flex-start;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.file-info {
  flex: 1;
}

.file-info p {
  margin: 5px 0;
  font-size: 14px;
}

.file-actions {
  margin-top: 10px;
}

.file-actions .el-button {
  margin-right: 10px;
}
</style>